<template>
  <n-button type="primary" @click="save">
    <template #icon>
      <n-icon>
        <Save />
      </n-icon>
    </template>
    {{ t("layout.header.Save") }}
  </n-button>
</template>
<script setup>
import { nextTick } from "vue";
import { Save } from "@vicons/carbon";
import { t } from "@/language";
import { zip } from "@/utils/common/pako";
import { useDrawingStore } from "@/store/modules/drawing";
import {
  DefaultScreenshot,
  useSceneInfoStore,
} from "@/store/modules/sceneInfo";
import { useGlobalConfigStore } from "@/store/modules/globalConfig";
import { useDispatchSignal } from "@/hooks/useSignal";
import { fetchUpload } from "@/http/api/sys";
import { filterSize } from "@/utils/common/file";
import { fetchUpdateScene } from "@/http/api/scenes";
import { Service } from "~/network";

const sceneInfoStore = useSceneInfoStore();
const drawingStore = useDrawingStore();
const globalConfigStore = useGlobalConfigStore();

function save() {
  // 检查对应sceneId的工程是否存在
  if (!sceneInfoStore.data.id) {
    window.$message?.error("该工程不存在!");
    return;
  }

  window.$dialog.warning({
    title: "警告",
    content: "确定更新该场景吗？",
    positiveText: "确定",
    negativeText: "取消",
    onPositiveClick: async () => {
      globalConfigStore.loadingText = "生成场景数据，请稍后";
      globalConfigStore.loading = true;

      // 版本自动 +1
      sceneInfoStore.setDataFieldValue(
        "sceneVersion",
        sceneInfoStore.data.sceneVersion + 1
      );

      const biz = `${sceneInfoStore.data.id}-V${sceneInfoStore.data.sceneVersion}`;

      let coverPicture = sceneInfoStore.data.coverPicture;
      // 如果生成了封面，则先上传封面
      if (coverPicture && coverPicture !== DefaultScreenshot) {
        const f = await fetch(coverPicture);
        const blob = await f.blob();
        const res = await fetchUpload({
          file: new File(
            [blob],
            `${sceneInfoStore.data.sceneName}-${Date.now()}.png`,
            { type: blob.type }
          ),
          biz: `upload/3DEditor/screenshot/${biz}`,
        });
        if (res.error === null) {
          sceneInfoStore.setDataFieldValue("coverPicture", res.data);
          coverPicture = res.data;
        } else {
          window.$message?.error("封面图保存失败");
        }
      }

      await nextTick();

      // 保存项目信息
      const sceneInfo = {
        ...sceneInfoStore.data,
        coverPicture,
        // 覆盖原zip包位置
        zip: "",
        hasDrawing: drawingStore.getIsUploaded ? 1 : 0,
        // 图纸信息
        drawingInfo: !drawingStore.getIsUploaded
          ? undefined
          : {
              imgSrc: drawingStore.getImgSrc,
              markList: zip(drawingStore.getMarkList),
              imgInfo: JSON.stringify(drawingStore.getImgInfo),
            },
      };

      globalConfigStore.loadingText = "场景正在压缩...";

      const packConfig = {
        // 首包名称
        name: `${sceneInfoStore.data.sceneName}`,
        // 拆分的最深层级 0:拆分至最深层
        layer: 3,
        // 场景其他信息（存入首包）
        sceneInfo,
        // 压缩包上传接口函数，多压缩包
        zipUploadFun: async (zipFile) => {
          const res = await fetchUpload({
            file: zipFile,
            biz: `upload/3DEditor/scene/${biz}`,
          });
          if (res.error !== null) {
            window.$message?.error("保存工程失败！");
            return "";
          }
          return res.data;
        },
        // 打包进度回调
        onProgress: (progress) => {
          globalConfigStore.loadingText = progress + "%";
        },
        // 打包完成回调
        onComplete: (data) => {
          const params = Object.assign(sceneInfo, {
            zip: data.firstUploadResult,
            zipSize: filterSize(data.totalSize),
          });
          params.drawingInfo = undefined;
          fetchUpdateScene(sceneInfoStore.data.id, params).then((res) => {
            globalConfigStore.loadingText = "保存成功！";

            sceneInfoStore.setData(res.data);
            setTimeout(() => {
              globalConfigStore.loading = false;
            }, 500);
          });
        },
      };

      window.viewer.modules.package.pack(packConfig);
    },
  });
}
</script>

<style lang="less" scoped></style>
